/* Classic Ladder Project */
/* Copyright (C) 2001-2012 Marc Le Douarain */
/* http://membres.lycos.fr/mavati/classicladder/ */
/* http://www.sourceforge.net/projects/classicladder */
/* December 2010 */
/* ------------------------------------------------------ */
/* Menus & Toolbar - GTK window                           */
/* ------------------------------------------------------ */
/* Many thanks to Heli Tejedor for his modified version   */
/* with idea of possible menus and toolbar feature        */
/* ------------------------------------------------------ */
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */
/* License as published by the Free Software Foundation; either */
/* version 2.1 of the License, or (at your option) any later version. */

/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
/* Lesser General Public License for more details. */

/* You should have received a copy of the GNU Lesser General Public */
/* License along with this library; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <gtk/gtk.h>

#include "classicladder.h"
#include "global.h"
#include "classicladder_gtk.h"
#include "print_gtk.h"
#include "edit_gtk.h"
#include "symbols_gtk.h"
#include "manager_gtk.h"
#include "config_gtk.h"
#include "spy_vars_gtk.h"
#include "log_events_gtk.h"
#include "monitor_threads.h"
#include "search.h"
#include "manager_gtk.h"
#include "monitor_windows_gtk.h"
#include "monitor_transfer.h"
#include "menu_and_toolbar_gtk.h"

GtkUIManager * uiManager;

static GtkActionEntry ActionEntriesArray[ ] =
{	{ "FileMenuAction", NULL, "File" },
	{ "NewAction", GTK_STOCK_NEW, "New", NULL, "Create a new project", G_CALLBACK( DoActionConfirmNewProject ) },
	{ "LoadAction", GTK_STOCK_OPEN, "Load", NULL, "Load an existing project", G_CALLBACK( DoActionLoadProject ) },
	{ "SaveAction", GTK_STOCK_SAVE, "Save", NULL, "Save current project", G_CALLBACK( DoActionSave ) },
	{ "SaveAsAction", NULL, "Save As...", "<Shift><Control>S", "Save project to another file", G_CALLBACK( DoActionSaveAs ) },
	{ "ExportMenuAction", NULL, "Export to", NULL, NULL, NULL },
	{ "ExportSvgAction", NULL, "Svg", NULL, NULL, G_CALLBACK( DoActionExportSvg ) },
	{ "ExportPngAction", NULL, "Png", NULL, NULL, G_CALLBACK( DoActionExportPng ) },
	{ "CopyToClipboardAction", NULL, "Clipboard", "<Control>C", NULL, G_CALLBACK( DoActionCopyToClipboard ) },
	{ "PreviewAction", GTK_STOCK_PRINT_PREVIEW, "Preview", "<Shift><Control>P", NULL, G_CALLBACK( PrintPreviewGtk ) },
	{ "PrintAction", GTK_STOCK_PRINT, "Print", "<Control>P", "Print current section", G_CALLBACK( PrintGtk ) },
	{ "QuitAction", GTK_STOCK_QUIT, "Quit", NULL, NULL, G_CALLBACK( ConfirmQuit ) },

	{ "ViewMenuAction", NULL, "View" },

	{ "FindMenuAction", NULL, "Search" },
	{ "FindOpenAction", GTK_STOCK_FIND, "Find", NULL, "Find First", G_CALLBACK( FunctionSearchOpenBox ) },
	{ "FindNextAction", GTK_STOCK_GO_FORWARD, "Find Next", "<Control>G", "Find Next", G_CALLBACK( SearchAndGoToNextElement ) },
	{ "FindPrevAction", GTK_STOCK_GO_BACK, "Find Previous", "<Shift><Control>G", "Find Down", G_CALLBACK( SearchAndGoToPreviousElement ) },
	{ "GoToFirstRungAction", GTK_STOCK_GOTO_TOP, "Go to First Rung", "<Control>T", "Go to First Rung", G_CALLBACK( GoToFirstRung ) },
	{ "GoToLastRungAction", GTK_STOCK_GOTO_BOTTOM, "Go to Last Rung", "<Shift><Control>T", "Go to Last Rung", G_CALLBACK( GoToLastRung ) },
	{ "GoToPrevSectionAction", NULL, "Go to Previous Section", "<Control>R", "Go to Previous Section", G_CALLBACK( SelectPreviousSectionInManager ) },
	{ "GoToNextSectionAction", NULL, "Go to Next Section", "<Shift><Control>R", "Go to Next Section", G_CALLBACK( SelectNextSectionInManager ) },

	{ "PLCAction", NULL, "PLC" },
#ifdef COMPLETE_PLC
	{ "ConnectDisconnectAction", GTK_STOCK_CONNECT, "ConnectDisconnect", NULL, "Connect/Disconnect", G_CALLBACK( DoFlipFlopConnectDisconnectTargetInGtk ) },
#endif
	{ "RunStopAction", GTK_STOCK_EXECUTE, "Run logic", NULL, "Start/stop logic", G_CALLBACK( DoFlipFlopRunStop ) },
	{ "ResetAction", GTK_STOCK_REFRESH, "Reset logic", NULL, "Reset logic", G_CALLBACK( DoActionResetAndConfirmIfRunning ) },
	{ "ConfigurationAction", GTK_STOCK_PREFERENCES, "Configuration", NULL, "Configuration (sizes, i/o, ...)", G_CALLBACK( OpenConfigWindowGtk ) },
#ifdef COMPLETE_PLC
	{ "SetTargetClockTimeAction", GTK_STOCK_CONNECT, "Set Target Clock Time", NULL, "Set Clock Time of the Target with PC Time", G_CALLBACK( MenuToSetTargetClockTime ) },
	{ "RebootTargetAction", NULL, "Reboot Target", NULL, "Ask to reboot the target", G_CALLBACK( MenuRebootTarget ) },
	{ "TransferMenuAction", NULL, "File Transfer", NULL, NULL, NULL },
	{ "SendProjectToTargetAction", NULL, "Send current project to Target", NULL, NULL, G_CALLBACK( MenuSendProjectToTargetAction ) },
	{ "ReceiveProjectFromTargetAction", NULL, "Receive project of Target", NULL, NULL, G_CALLBACK( MenuReceiveProjectFromTargetAction ) },
#endif

	{ "HelpMenuAction", NULL, "Help" },
	{ "AboutAction", NULL, "About", "F1", NULL, G_CALLBACK( DoActionAboutClassicLadder ) },	
};
static GtkToggleActionEntry ToggleActionEntriesArray[ ] =
{	{ "ViewSectionsAction", GTK_STOCK_DND_MULTIPLE, "Sections window", "F2", "View sections manager window", G_CALLBACK( OpenManagerWindow ), TRUE },
	{ "ViewEditorAction", GTK_STOCK_EDIT, "Editor window", "F3", "View editor window", G_CALLBACK( OpenEditWindow ), FALSE },
	{ "ViewSymbolsAction", GTK_STOCK_INDEX, "Symbols window", "F4", "View symbols window", G_CALLBACK( OpenSymbolsWindow ), FALSE },
	{ "ViewBoolVarsAction", NULL, "Bools vars window", "F5", NULL, G_CALLBACK( OpenSpyBoolVarsWindow ), FALSE },
	{ "ViewFreeVarsAction", NULL, "Free vars window", "F6", NULL, G_CALLBACK( OpenSpyFreeVarsWindow ), FALSE },
#ifdef COMPLETE_PLC
	{ "ViewLogAction", NULL, "Log window", "F7", NULL, G_CALLBACK( OpenLogBookWindow ), FALSE },
#endif
	{ "ViewMonitorAction", NULL, "Target monitor frames window", NULL, NULL, G_CALLBACK( OpenMonitorWindow ), FALSE },
};

static const gchar *ClassicLadder_ui_strings = 
"<ui>"
"	<menubar name='MenuBar'>"
"		<menu action='FileMenuAction'>"
"			<menuitem action='NewAction' />"
"			<menuitem action='LoadAction' />"
"			<menuitem action='SaveAction' />"
"			<menuitem action='SaveAsAction' />"
"			<separator />"
"			<menu action='ExportMenuAction'>"
"				<menuitem action='ExportSvgAction' />"
"				<menuitem action='ExportPngAction' />"
"				<menuitem action='CopyToClipboardAction' />"
"			</menu>"
"			<separator />"
"			<menuitem action='PreviewAction' />"
"			<menuitem action='PrintAction' />"
"			<separator />"
"			<menuitem action='QuitAction' />"
"		</menu>"
"		<menu action='FindMenuAction'>"
"			<menuitem action='FindOpenAction' />"
"			<menuitem action='FindNextAction' />"
"			<menuitem action='FindPrevAction' />"
"			<separator />"
"			<menuitem action='GoToFirstRungAction' />"
"			<menuitem action='GoToLastRungAction' />"
"			<separator />"
"			<menuitem action='GoToPrevSectionAction' />"
"			<menuitem action='GoToNextSectionAction' />"
"		</menu>"
"		<menu action='ViewMenuAction'>"
"			<menuitem action='ViewSectionsAction' />"
"			<menuitem action='ViewEditorAction' />"
"			<menuitem action='ViewSymbolsAction' />"
"			<menuitem action='ViewBoolVarsAction' />"
"			<menuitem action='ViewFreeVarsAction' />"
#ifdef COMPLETE_PLC
"			<menuitem action='ViewLogAction' />"
#endif
"			<menuitem action='ViewMonitorAction' />"
"		</menu>"
"		<menu action='PLCAction'>"
#ifdef COMPLETE_PLC
"			<menuitem action='ConnectDisconnectAction' />"
#endif
"			<separator />"
"			<menuitem action='RunStopAction' />"
"			<menuitem action='ResetAction' />"
"			<separator />"
"			<menuitem action='ConfigurationAction' />"
"			<separator />"
#ifdef COMPLETE_PLC
"			<menuitem action='SetTargetClockTimeAction' />"
"			<menuitem action='RebootTargetAction' />"
#endif
"			<separator />"
"			<menu action='TransferMenuAction'>"
"				<menuitem action='SendProjectToTargetAction' />"
"				<menuitem action='ReceiveProjectFromTargetAction' />"
"			</menu>"
"		</menu>"
"		<menu action='HelpMenuAction'>"
"			<menuitem action='AboutAction' />"
"		</menu>"
"	</menubar>"
"	<toolbar name='ToolBar'>"
"		<toolitem action='NewAction' />"
"		<toolitem action='LoadAction' />"
"		<toolitem action='SaveAction' />"
"		<separator />"
"		<toolitem action='PrintAction' />"
"		<separator />"
"		<toolitem action='RunStopAction' />"
"		<toolitem action='ResetAction' />"
"		<toolitem action='ConfigurationAction' />"
"		<separator />"
"		<toolitem action='ViewSectionsAction' />"
"		<toolitem action='ViewEditorAction' />"
"		<toolitem action='ViewSymbolsAction' />"
"		<separator />"
"	</toolbar>"
"</ui>";

GtkUIManager * InitMenusAndToolBar( GtkWidget *vbox )
{
	GtkActionGroup * ActionGroup;
	GError *error = NULL;
	uiManager = gtk_ui_manager_new( );
	
	ActionGroup = gtk_action_group_new( "ClassicLadderActionGroup" );
	gtk_action_group_add_actions( ActionGroup, ActionEntriesArray, G_N_ELEMENTS( ActionEntriesArray ), NULL );
	gtk_action_group_add_toggle_actions( ActionGroup, ToggleActionEntriesArray, G_N_ELEMENTS( ToggleActionEntriesArray ), NULL/*user_data*/ );
	
	gtk_ui_manager_insert_action_group( uiManager, ActionGroup, 0 );
	if (!gtk_ui_manager_add_ui_from_string( uiManager, ClassicLadder_ui_strings, -1/*length*/, &error ))
	{
		g_message ("Failed to build gtk menus: %s", error->message);
		g_error_free (error);
	}
	else
	{
		GtkWidget * ToolBarWidget = gtk_ui_manager_get_widget( uiManager, "/ToolBar" );
		gtk_box_pack_start( GTK_BOX(vbox), gtk_ui_manager_get_widget( uiManager, "/MenuBar" ), FALSE, FALSE, 0 );
		//do not display text under icons (seems to be the case per default under Windows...)
		gtk_toolbar_set_style( GTK_TOOLBAR(ToolBarWidget), GTK_TOOLBAR_ICONS );
//		gtk_toolbar_set_style( GTK_TOOLBAR(ToolBarWidget), GTK_TOOLBAR_BOTH );
		gtk_box_pack_start( GTK_BOX(vbox), ToolBarWidget, FALSE, FALSE, 0 );
	}
	return uiManager;
}

void EnableDisableMenusAccordingSectionType( )
{
	int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language;
	GtkWidget * MenuElement;
	MenuElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/FindMenuAction/GoToFirstRungAction" );
	gtk_widget_set_sensitive( MenuElement, !(iCurrentLanguage==SECTION_IN_SEQUENTIAL) );
	MenuElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/FindMenuAction/GoToLastRungAction" );
	gtk_widget_set_sensitive( MenuElement, !(iCurrentLanguage==SECTION_IN_SEQUENTIAL) );
}

// called at startup (if window saved open or not), and when window closed...
void SetToogleMenuForSectionsManagerWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewSectionsAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
void SetToggleMenuForEditorWindow( gboolean OpenedWin )
{
//printf("SetToggleMenuForEditorWindow function called with state %d!\n",OpenedWin);
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewEditorAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
void SetToggleMenuForSymbolsWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewSymbolsAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
void SetToggleMenuForBoolVarsWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewBoolVarsAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
void SetToggleMenuForFreeVarsWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewFreeVarsAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
#ifdef COMPLETE_PLC
void SetToggleMenuForLogWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewLogAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}
#endif
void SetToggleMenuForMonitorWindow( gboolean OpenedWin )
{
	GtkWidget *ToggleElement = gtk_ui_manager_get_widget( uiManager, "/MenuBar/ViewMenuAction/ViewMonitorAction" );
	gtk_check_menu_item_set_state( GTK_CHECK_MENU_ITEM(ToggleElement), OpenedWin );
}

//toggle function ourself, depends on "status running/stopped..." 
void SetGtkMenuStateForRunStopSwitch( gboolean Running )
{
	GtkWidget *Element = gtk_ui_manager_get_widget( uiManager, "/MenuBar/PLCAction/RunStopAction" );
	gtk_menu_item_set_label( GTK_MENU_ITEM(Element), Running?"Stop logic":"Run logic" );
	
	Element = gtk_ui_manager_get_widget( uiManager, "/ToolBar/RunStopAction" );
	gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(Element), Running?GTK_STOCK_STOP:GTK_STOCK_EXECUTE );
	gtk_tool_button_set_label( GTK_TOOL_BUTTON(Element), Running?"Stop":"Run" );
	gtk_tool_item_set_tooltip_text( GTK_TOOL_ITEM(Element), Running?"Stop logic":"Run logic" );
}

#ifdef COMPLETE_PLC
void SetGtkMenuStateForConnectDisconnectSwitch( gboolean TargetConnected )
{
	GtkWidget *Element = gtk_ui_manager_get_widget( uiManager, "/MenuBar/PLCAction/ConnectDisconnectAction" );
	gtk_menu_item_set_label( GTK_MENU_ITEM(Element), TargetConnected?"Disconnect":"Connect" );
}
#endif


#ifdef COMPLETE_PLC
void MenuToSetTargetClockTime( void )
{
	if ( !InfosGUI->TargetMonitor.RemoteConnected )
		ShowMessageBox("Error", "You are not currently connected to a remote target...","Ok");
	else
		InfosGUI->TargetMonitor.AskTargetToSetClockTime = 1;
}
void MenuRebootTarget( void )
{
	if ( !InfosGUI->TargetMonitor.RemoteConnected )
		ShowMessageBox("Error", "You are not currently connected to a remote target...","Ok");
	else
		InfosGUI->TargetMonitor.AskTargetToReboot = 1;
}
void MenuSendProjectToTargetAction( void )
{
	if ( OpenDialogMonitorConnect( ) )
	{
printf("HERE SET REMOTE_FILE_TRANSFER SEND!\n");
		InfosGUI->TargetMonitor.TransferFileNum = 0;
		InfosGUI->TargetMonitor.TransferFileIsSend = TRUE;
		TransferMasterStart( );
	}
}
void MenuReceiveProjectFromTargetAction( void )
{
	if ( OpenDialogMonitorConnect( ) )
	{
printf("HERE SET REMOTE_FILE_TRANSFER RECEIVE!\n");
		InfosGUI->TargetMonitor.TransferFileNum = 0;
		InfosGUI->TargetMonitor.TransferFileIsSend = FALSE;
		TransferMasterStart( );
	}
}
#endif

